package App.Repository;

import App.Model.Account.*;
import App.Model.BaseEnum;
import App.Model.Friend.CrmFriend;
import App.Model.LoginRequest;
import App.Model.Project.CommonItem;
import App.Model.RegisterRequest;
import App.Model.User;
import App.Model.Version.CrmAppVersion;
import com.sun.org.apache.bcel.internal.generic.FADD;
//import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import org.hibernate.Transaction;
import org.hibernate.query.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Logger;

/**
 * Created by xw on 2018/11/12.
 */


@Repository
public class AccountRepository extends BaseRepository {

    Logger _log = Logger.getLogger("BookRepository");

    public List<CrmUser> select() {
        String strSql = "select * from crm_user";
        List<CrmUser> _list = new ArrayList<>();
        try {
            _list = getEntitys(strSql, null, CrmUser.class);

        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
        return _list;
    }

    //检测用户是否存在
    public CrmUser selectUser(LoginRequest _request) {
        try {
            String strSql = "select id,username,password,recstatus,realname from crm_user where username=:username and islogin ='0'";
            Map<String, Object> _params = new HashMap<>();
            _params.put("username", _request.getUsername());
            List<CrmUser> _list = getEntitys(strSql, _params, CrmUser.class);
            if (_list != null && _list.size() > 0) {
                return _list.get(0);
            } else {
                return null;
            }
        } catch (Exception ex) {
            throw ex;
        }
    }

    //添加用户
    @Transactional
    public int register(RegisterRequest _request) {

        //判断用户名是否重复
        int result = 0;
        try {
            String strSql = "insert into crm_user(username,password,realname,lawyerphoto,title,recstatus)" +
                    " values(:username,:password,:realname,:lawyerphoto,:title,1) ";

            Map<String, Object> _params = new HashMap<>();
            _params.put("username", _request.getUsername());
            _params.put("password", _request.getPassword());
            _params.put("realname", _request.getRealname());
            _params.put("lawyerphoto", _request.getLawyerphoto());
            _params.put("title", _request.getTitle());
            result = updateEntity(strSql, _params);
        } catch (Exception ex) {
            throw ex;
        }
        return result;
    }


    //修改密码
    @Transactional
    public int changePassword(String phone, String oldPassword, String newPassword) {
        int _resuslt = 0;

        String _strSql = "select * from crm_user where recstatus=1 and  username=:username ";
        Map<String, Object> _params = new HashMap<>();
        _params.put("username", phone);
        // _params.put("password", oldPassword);
        List<CrmUser> _users = getEntitys(_strSql, _params, CrmUser.class);

        if (_users != null && _users.size() > 0) {
            CrmUser _user = _users.get(0);
            int _userid = _user.getId();
            _strSql = " update crm_user set password=:password where id=:id ";
            _params.clear();
            _params.put("id", _userid);
            _params.put("password", newPassword);
            _resuslt = updateEntity(_strSql, _params);
        } else {

            //用户名或者密码错误
            _resuslt = -1;
        }
        return _resuslt;
    }

    //更新用户信息
    @Transactional
    public int updateUserProfile(UpdateUserInfoRequest _request, int userid) {

        String _strSql = "update crm_user " +
                " set realname=:realname," +
                " headimage=:headimage," +
                " gender=:gender, " +
                " title=:title," +
                " company=:company," +
                "address=:address," +
                " signature=:signature " +
                " where id=:id";

        Map<String, Object> _params = new HashMap<>();
        _params.put("realname", _request.getRealname());
        _params.put("gender", _request.getGender());
        _params.put("title", _request.getTitle());
        _params.put("company", _request.getCompany());
        _params.put("address", _request.getAddress());
        _params.put("signature", _request.getSignature());
        _params.put("headimage", _request.getHeadimage());
        _params.put("id", userid);

        return updateEntity(_strSql, _params);

    }

    public List<CrmDataItem> getLawyerExpertises() {
        String _strSql = " select recid,recname,recorder  from crm_user_auth_expertise order by recorder asc ";
        return getEntitys(_strSql, null, CrmDataItem.class);
    }

    @Transactional
    public int authUser(AuthUserRequest _request, int userid) throws Exception {

        String _strSql = " insert into crm_user_auth(recid,userid,authtype,workbegindate,lawoffice,workarea,lawyernumber," +
                " certificate,expertiseid,resume,experience,education," +
                " title,reward,litigationcase,headimage,certificate_back,expertiseids)" +
                " values(:recid,:userid,:authtype,:workbegindate,:lawoffice,:workarea,:lawyernumber," +
                ":certificate,:expertiseid,:resume,:experience,:education," +
                ":title,:reward,:litigationcase,:headimage,:certificate_back,:expertiseids);  ";

        // ,:,:expertiseids
        Map<String, Object> _params = new HashMap<>();
        _params.put("recid", UUID.randomUUID().toString());
        _params.put("userid", userid);
        _params.put("authtype", _request.getAuthtype());

        Date _beginTime = null;
        if (_request.getWorkbegindate() != null && !_request.getWorkbegindate().isEmpty()) {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            _beginTime = df.parse(_request.getWorkbegindate());
        }

        //string to data
        _params.put("workbegindate", _beginTime);
        _params.put("lawoffice", _request.getLawoffice());
        _params.put("workarea", _request.getWorkarea());
        _params.put("lawyernumber", _request.getLawyernumber());
        _params.put("certificate", _request.getCertificate());
        _params.put("expertiseid", _request.getExpertiseid());
        _params.put("resume", _request.getResume());
        _params.put("experience", _request.getExperience());
        _params.put("education", _request.getEducation());
        _params.put("title", _request.getTitle());
        _params.put("reward", _request.getReward());
        _params.put("litigationcase", _request.getLitigationcase());
        _params.put("headimage", _request.getHeadimage());
        _params.put("certificate_back", _request.getCertificate_back());
        _params.put("expertiseids", _request.getExpertiseids());
        return updateEntity(_strSql, _params);
    }

    @Transactional
    public int updateAuthUser(AuthUserRequest _request, int userid) throws Exception {

        String _strSql = " update crm_user_auth set " +
                "   authtype          =:authtype         ," +
                "  workbegindate     =:workbegindate    ," +
                "  lawoffice         =:lawoffice        ," +
                "  workarea          =:workarea         ," +
                "  lawyernumber      =:lawyernumber     ," +
                "  certificate       =:certificate      ," +
                "  expertiseid       =:expertiseid      ," +
                "  resume            =:resume           ," +
                "  experience        =:experience       ," +
                "  education         =:education        ," +
                "  title             =:title            ," +
                "  reward            =:reward           ," +
                "  litigationcase    =:litigationcase  ,  " +
                "  headimage=:headimage, " +
                "  certificate_back=:certificate_back, " +
                "  expertiseids=:expertiseids " +
                "  where recid=:recid ";


        Map<String, Object> _params = new HashMap<>();
        _params.put("recid", _request.getRecid());
        _params.put("authtype", _request.getAuthtype());


        Date _beginTime = null;
        if (_request.getWorkbegindate() != null && !_request.getWorkbegindate().isEmpty()) {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            _beginTime = df.parse(_request.getWorkbegindate());
        }

        //string to data
        _params.put("workbegindate", _beginTime);
        _params.put("lawoffice", _request.getLawoffice());
        _params.put("workarea", _request.getWorkarea());
        _params.put("lawyernumber", _request.getLawyernumber());
        _params.put("certificate", _request.getCertificate());
        _params.put("expertiseid", _request.getExpertiseid());
        _params.put("resume", _request.getResume());
        _params.put("experience", _request.getExperience());
        _params.put("education", _request.getEducation());
        _params.put("title", _request.getTitle());
        _params.put("reward", _request.getReward());
        _params.put("litigationcase", _request.getLitigationcase());
        _params.put("headimage", _request.getHeadimage());
        _params.put("certificate_back", _request.getCertificate_back());
        _params.put("expertiseids", _request.getExpertiseids());

       int _result=  updateEntity(_strSql, _params);
        if(_result>0){
            _strSql=" update  crm_user set company=:company,title=:title where id=:id";
            _params.clear();
            _params.put("company", _request.getLawoffice());
            _params.put("title", _request.getAuthtype());
            _params.put("id", userid);

            updateEntity(_strSql, _params);
        }


        return _result;


    }


    public List<AuthUserList> getLawyerAuthList(int userid) {
        String _strSql = " select recid,authtype,workbegindate,lawoffice," +
                " workarea,lawyernumber,certificate,expertiseid,resume, " +
                " experience,education,title,reward,litigationcase,passtype,headimage,certificate_back,expertiseids " +
                " from crm_user_auth " +
                " where recstatus=1 " +
                " and  userid=:userid " +
                " order by createtime desc ";

        Map<String, Object> _params = new HashMap<>();
        _params.put("userid", userid);
        List<AuthUserList> _outResult = new ArrayList<>();
        List<CrmAuthUser> _result = getEntitys(_strSql, _params, CrmAuthUser.class);
        SimpleDateFormat _dataFormat = new SimpleDateFormat("yyyy-MM-dd");
        for (CrmAuthUser u : _result) {
            String _strBegindate = "";
            if (u.getWorkbegindate() != null) {
                _strBegindate = _dataFormat.format(u.getWorkbegindate());
            }

            AuthUserList _auth = new AuthUserList();
            _auth.setRecid(u.getRecid());
            _auth.setAuthtype(u.getAuthtype());
            _auth.setWorkbegindate(_strBegindate);
            _auth.setLawoffice(u.getLawoffice());
            _auth.setWorkarea(u.getWorkarea());
            _auth.setLawyernumber(u.getLawyernumber());
            _auth.setCertificate(u.getCertificate());
            _auth.setExpertiseid(u.getExpertiseid());
            _auth.setResume(u.getResume());
            _auth.setExperience(u.getExperience());
            _auth.setEducation(u.getEducation());
            _auth.setTitle(u.getTitle());
            _auth.setReward(u.getReward());
            _auth.setLitigationcase(u.getLitigationcase());
            _auth.setHeadimage(u.getHeadimage());
            _auth.setCertificate_back(u.getCertificate_back());
            _auth.setExpertiseids(u.getExpertiseids());

            if (u.getPasstype() == 1) {
                _auth.setIspassed(true);
            } else {
                _auth.setIspassed(false);
            }
            _outResult.add(_auth);
        }
        return _outResult;
    }


    public AuthUserProcess getLawyerAuthProcess(int userid) {

        String _strSql = " select recid,authtype,workbegindate,lawoffice," +
                " workarea,lawyernumber,certificate,expertiseid,resume, " +
                " experience,education,title,reward,litigationcase,passtype,headimage,certificate_back,expertiseids " +
                " from crm_user_auth " +
                " where recstatus=1 " +
                " and  userid=:userid " +
                " order by createtime desc ";

        AuthUserProcess _process = new AuthUserProcess();
        _process.setAuthtype(BaseEnum.AuthUserType.Lawyer.getAuthUserType());

        Map<String, Object> _params = new HashMap<>();
        _params.put("userid", userid);
        List<CrmAuthUser> _result = getEntitys(_strSql, _params, CrmAuthUser.class);
        //  Optional<CrmAuthUser> _theAuthUser = _result.stream().filter(x -> x.getAuthtype() == BaseEnum.AuthUserType.Lawyer.getAuthUserType()).findFirst();
        Optional<CrmAuthUser> _theAuthUser = _result.stream().findFirst();
        if (_theAuthUser.isPresent()) {
            if (_theAuthUser.get().getPasstype() == BaseEnum.AuthUserPassStatus.Passed.getAuthUserPassStatus()) {
                _process.setAuthprocess(BaseEnum.AuthUserProcess.Authed.getAuthUserProcess());
            } else {
                _process.setAuthprocess(BaseEnum.AuthUserProcess.Authing.getAuthUserProcess());
            }
        } else {
            _process.setAuthprocess(BaseEnum.AuthUserProcess.UnAuth.getAuthUserProcess());
        }
        return _process;
    }


    public CrmUserDetail getUserInfo(int theUserId) {

        String _strSql = " select  u.id,u.realname,u.username,u.headimage,u.gender,u.title,u.company,u.address,u.signature " +
                " from crm_user u  where u.id=:userid  ";

        Map<String, Object> _params = new HashMap<>();
        _params.put("userid", theUserId);
        List<CrmUserDetail> _users = getEntitys(_strSql, _params, CrmUserDetail.class);

        return _users.get(0);
    }

    /**
     * 根据登录名获取用户信息
     * @param userName
     * @return
     */
    public CrmUserDetail getUserInfoByPhone(String userName) {

        String _strSql = " select  u.id,u.realname,u.username,u.headimage,u.gender,u.title,u.company,u.address,u.signature " +
                " from crm_user u  where u.username=:username  ";

        Map<String, Object> _params = new HashMap<>();
        _params.put("username", userName);
        List<CrmUserDetail> _users = getEntitys(_strSql, _params, CrmUserDetail.class);

        return _users.get(0);
    }

    public CrmAppVersion getVersionNO(int appType) {

        String _strSql = " select recid,versioncode,versionname,downloadurl,enforceupdate " +
                " from  crm_app_version where apptype=:apptype ";

        Map<String, Object> _params = new HashMap<>();
        _params.put("apptype", appType);
        List<CrmAppVersion> _versions = getEntitys(_strSql, _params, CrmAppVersion.class);

        if (_versions != null && _versions.size() > 0) {
            return _versions.get(0);
        } else {
            return null;
        }
    }

    public List<CrmUser> GetAuthUsers() {

        String _strSql = " select u.id,u.username,u.password,u.recstatus,u.realname " +
                " from crm_user u  " +
                " inner join crm_user_auth a on u.id=a.userid " +
                " where u.recstatus=1 ";

        List<CrmUser> _users = getEntitys(_strSql, null, CrmUser.class);
        return _users;
    }

    @Transactional
    public int InsertTokenHistory(int userid, String token, Date _newExpiretionDate, String oldToken) {

        int _result = 0;

        String _strSql = "insert into crm_sys_token(recid,userid,token,expiretime,latestcallapitime,parent_token)" +
                " values(:recid,:userid,:token,:expiretime,now(),:parent_token) ";

        Map<String, Object> _params = new HashMap<>();
        _params.put("recid", UUID.randomUUID().toString());
        _params.put("userid", userid);
        _params.put("token", token);
        _params.put("expiretime", _newExpiretionDate);
        _params.put("parent_token", oldToken);
        _result = updateEntity(_strSql, _params);
        return _result;
    }

    @Transactional
    public int UpdateToken(String token) {
        int _result = 0;
        String _strSql = " update  crm_sys_token  set (recid,userid,token,expiretime,latestcallapitime)  where token=:token";

        Map<String, Object> _params = new HashMap<>();
        _params.put("recid", UUID.randomUUID().toString());
        // _params.put("userid", userid);
        _params.put("token", token);
        _result = updateEntity(_strSql, _params);
        return _result;
    }


    //更新token访问API的时间，调用一次API就更新一次
    @Transactional
    public int UpdateTokenLatestCallApiTime(String token) {

        int _result = 0;
        String _strSql = " update  crm_sys_token  set latestcallapitime=now()  where isvalid=true and  token=:token";
        Map<String, Object> _params = new HashMap<>();
        _params.put("token", token);
        _result = updateEntity(_strSql, _params);
        return _result;
    }

    //是否需要新的token，如果距离上次调用API超过5分钟，就生成新的token
    public boolean NeedCreateNewToken(String token) {

        boolean _needUpdate = false;
        String _strSql = " select count(1) from crm_sys_token  where isvalid=true " +
                " and expiretime>=now() " +
                " and token=:token " +
                " and TIMESTAMPDIFF(Second,latestcallapitime,now())>=300 ";
        Map<String, Object> _params = new HashMap<>();
        _params.put("token", token);

        int _theCount = getEntityCount(_strSql, _params);
        if (_theCount > 0) {


            return true;
        } else {
            return false;
        }
    }

    public CrmToken GetTokens(String token) {

        String _strSql = " select recid, token,parent_token from crm_sys_token  where isvalid=true " +
                " and expiretime>=now() " +
                " and parent_token=:token ";

        Map<String, Object> _params = new HashMap<>();
        _params.put("token", token);

        List<CrmToken> _list = getEntitys(_strSql, _params, CrmToken.class);
        if (_list != null && _list.size() > 0) {
            CrmToken _theToken = _list.get(0);

            return  _theToken;
        }
        return  null;
    }

    public boolean IsTokenValid(String token) {

        boolean _needUpdate = false;
        String _strSql = " select count(1) from crm_sys_token  where isvalid=true " +
                " and expiretime>=now() " +
                " and token=:token ";
        Map<String, Object> _params = new HashMap<>();
        _params.put("token", token);
        int _theCount = getEntityCount(_strSql, _params);
        if (_theCount > 0) {
            return true;
        } else {
            return false;
        }
    }

    @Transactional
    public int UpdateTokenInvalid(String token) {

        int _result = 0;
        String _strSql = " update crm_sys_token set isvalid=0 where token=:token";
        Map<String, Object> _params = new HashMap<>();
        _params.put("token", token);
        _result = updateEntity(_strSql, _params);
        return _result;
    }

    @Transactional
    public int UpdateTokenValid(Date expireTime, String newToken, String oldToken) {

        int _result = 0;
        String _strSql = " update crm_sys_token set isvalid=1, expiretime=:expireTime, token=:newToken where token=:oldToken";
        Map<String, Object> _params = new HashMap<>();
        _params.put("expireTime", expireTime);
        _params.put("newToken", newToken);
        _params.put("oldToken", oldToken);
        _result = updateEntity(_strSql, _params);
        return _result;
    }

    //检测用户是否存在
    public CrmUser getUserByToken(String token) {
        try {
            String strSql = " select u.id,u.username,u.password,u.recstatus,u.realname from crm_user u " +
                    " inner join crm_sys_token t on u.id =  t.userid " +
                    " where  t.token = :token ";
            Map<String, Object> _params = new HashMap<>();
            _params.put("token", token);
            List<CrmUser> _list = getEntitys(strSql, _params, CrmUser.class);
            if (_list != null && _list.size() > 0) {
                return _list.get(0);
            } else {
                return null;
            }
        } catch (Exception ex) {
            throw ex;
        }
    }

    @Transactional
    public int InsertUserLoginHistory(int userid, String version, int clientType, int loginResult, String optmethod) {

        int _result = 0;

        String _strSql = "insert into crm_user_login_history(recid,userid,version,recstatus,logintime,clienttype,loginresult,optmethod)" +
                " values(:recid,:userid,:version,:recstatus,now(),:clienttype,:loginresult,:optmethod) ";

        Map<String, Object> _params = new HashMap<>();
        _params.put("recid", UUID.randomUUID().toString());
        _params.put("userid", userid);
        _params.put("version", version);
        _params.put("recstatus", 1);
        _params.put("clienttype", clientType);
        _params.put("loginresult", loginResult);
        _params.put("optmethod", optmethod);
        _result = updateEntity(_strSql, _params);
        return _result;
    }

    public Date GetWebLoginTime(int userid) {
        String _strSql = " select logintime from  crm_user_login_history where userid=:userid and clienttype='3' and  optmethod='gettoken'  order by logintime desc limit 1  ";
        Map<String, Object> _params = new HashMap<>();
        _params.put("userid", userid);
        Date logintime = getEntitValue(_strSql, _params);
        return  logintime;
    }
    /**
     * 注销
     * @param userId
     * @return
     */
    @Transactional
    public int updateIslogin(int userId) {
        int _result = 0;
        String _strSql = " update crm_user set islogin='1' where id=:id";
        Map<String, Object> _params = new HashMap<>();
        _params.put("id", userId);
        _result = updateEntity(_strSql, _params);
        return _result;
    }
    //end of class

    public CrmToken GetTokensByUserId(int userid) {

        String _strSql = " select recid, token,parent_token from crm_sys_token  where isvalid=1 " +
                " and userid=:userid order by createtime desc";

        Map<String, Object> _params = new HashMap<>();
        _params.put("userid", userid);

        List<CrmToken> _list = getEntitys(_strSql, _params, CrmToken.class);
        if (_list != null && _list.size() > 0) {
            CrmToken _theToken = _list.get(0);

            return  _theToken;
        }
        return  null;
    }

    @Transactional
    public int UpdateTokenInvalidByUserId(int userId) {

        int _result = 0;
        String _strSql = " update crm_sys_token set isvalid=0 where userid=:userid and expiretime>=now()";
        Map<String, Object> _params = new HashMap<>();
        _params.put("userid", userId);
        _result = updateEntity(_strSql, _params);
        return _result;
    }

    public CrmToken getTokenByUserName(String phone) {

        String _strSql = " select cst.recid, cst.token,cst.parent_token from crm_sys_token  cst left join crm_user u on cst.userid = u.id" +
                " where  u.username=:username and cst.expiretime>=now() and cst.isvalid=1 order by cst.createtime desc";

        Map<String, Object> _params = new HashMap<>();
        _params.put("username", phone);

        List<CrmToken> _list = getEntitys(_strSql, _params, CrmToken.class);
        if (_list != null && _list.size() > 0) {
            CrmToken _theToken = _list.get(0);

            return  _theToken;
        }
        return  null;
    }

    public CrmToken getTokenByUserId(int userid) {
        String _strSql = " select recid, token,parent_token from crm_sys_token  " +
                " where userid=:userid order by createtime desc limit 1";

        Map<String, Object> _params = new HashMap<>();
        _params.put("userid", userid);

        List<CrmToken> _list = getEntitys(_strSql, _params, CrmToken.class);
        if (_list != null && _list.size() > 0) {
            CrmToken _theToken = _list.get(0);

            return  _theToken;
        }
        return  null;
    }
}



